﻿using FastData.Caching;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FastData
{
    public class Procedure : QueryBase
    {
        public string Name;

        public Procedure(DataAccess data)
            : base(data)
        {
            CommandType = CommandType.StoredProcedure;
        }

        internal override string GetCommandText(ExecuteType type)
        {
            return Data.Provider.CreateProcedureText(this, type);
        }

        public Procedure Param(string name, object value)
        {
            base.AddParameter(name, value);
            return this;
        }

        public Procedure Param(DbParameter parameter)
        {
            base.AddParameter(parameter);
            return this;
        }

        public Procedure Cache(TimeSpan slidingExpiration)
        {
            SlidingExpiration = slidingExpiration;
            return this;
        }

        public Procedure Cache(DateTime absoluteExpiration)
        {
            AbsoluteExpiration = absoluteExpiration;
            return this;
        }

        public Procedure CacheDependency(TableDependency tableDependency)
        {
            CacheDependencies.Add(tableDependency);
            return this;
        }

        public Procedure CacheDependency(string tableName)
        {
            return CacheDependency(tableName, null);
        }

        public Procedure CacheDependency(string tableName, string id)
        {
            return CacheDependency(new TableDependency(tableName, id));
        }

        public int Execute()
        {
            return Data.ExecuteNonQuery(this);
        }

        public async Task<int> ExecuteAsync()
        {
            return await Data.ExecuteNonQueryAsync(this);
        }

        public DataTable ExecuteDataTable()
        {
            return Data.ExecuteDataTable(this);
        }

        public IEnumerable<T> Execute<T>()
        {
            return Data.Execute<T>(this);
        }

        public object ExecuteScalar()
        {
            return Data.ExecuteScalar(this);
        }

        public T ExecuteScalar<T>()
        {
            return (T)ExecuteScalar();
        }

        public DataRow ExecuteDataRow()
        {
            return Data.GetDataRow(this.ExecuteDataTable());
        }

        public async Task<object> ExecuteScalarAsync()
        {
            return await Data.ExecuteScalarAsync(this);
        }

        public async Task<DbDataReader> ExecuteReaderAsync()
        {
            return await Data.ExecuteReaderAsync(this);
        }

        public DbDataReader ExecuteReader()
        {
            return Data.ExecuteReader(this);
        }

        public void ExecuteLazy()
        {
            Data.ExecuteLazy(this);
        }

        public async Task<DataTable> ExecuteDataTableAsync()
        {
            return await Data.ExecuteDataTableAsync(this);
        }

        public async Task<IEnumerable<T>> ExecuteListAsync<T>()
        {
            return await Data.ExecuteAsync<T>(this);
        }
    }
}
